package pay.serviceImpl;

import java.io.IOException;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.annotation.Resource;

import org.hibernate.internal.util.StringHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import org.springframework.web.client.RestTemplate;
import pay.common.ConstantFYJZH;
import pay.common.HqlFilter;
import pay.common.PayConstants;
import pay.entity.OrderInfo;
import pay.entity.ProductInfo;
import pay.entity.Trade;
import pay.service.IOrderJpa;
import pay.service.IProduct;
import pay.service.ITrade;
import pay.serviceImpl.dao.base.impl.BaseServiceImpl;
import pay.utils.*;

@Service
public class TradeImpl extends BaseServiceImpl<Trade> implements ITrade {

	private Logger logger = LoggerFactory.getLogger(TradeImpl.class);

	@Resource
	private JdbcTemplate jdbcTemplate;

	@Autowired
	private RestTemplate template;

	@Autowired
	private IOrderJpa orderJpa;


	@Autowired
	private IProduct productJpa;

	@Value("${errorMsgPhoneListStr}")
	private String errorMsgPhoneListStr;

	@Value("${errorMsgMailListStr}")
	private String errorMsgMailListStr;


	@Override
	public Trade findById(Long id) {
		return this.findById(id);
	}

	@Override
	public Trade findByType(Integer type) {
		Trade result = null;
		if (type == null) {
			return null;
		} else {
			HqlFilter hqlFilter = new HqlFilter();
			hqlFilter.addEQFilter("type", type);

			List<Trade> tradeList = this.findByFilter(hqlFilter);
			if (tradeList != null && tradeList.size() > 0) {
				result = tradeList.get(0);
			}
		}

		return result;

	}

	@Override
	public List<Trade> getAll(Long userId, Long startTime, Long endTime,
			Integer tradeType, Integer curpage, Integer pageSize) {


		HqlFilter hqlFilter = new HqlFilter();

		hqlFilter.addEQFilter("userId", userId);
//		hqlFilter.addEQFilter("resp_code", "0000");
		hqlFilter.addSql(" and showStatus = 1 and  cts > " + startTime + " and cts <" + endTime + " and type != 4");

		
		hqlFilter.addSort("cts");
		hqlFilter.addOrder("desc");

		List<Trade> tradeList = findByFilter(hqlFilter, curpage, pageSize);

		return tradeList;

	}

	@Override
	public Integer getTotalNum(Long userId, Long startTime, Long endTime) {


		HqlFilter hqlFilter = new HqlFilter();
		hqlFilter.addEQFilter("showStatus", 1);
		hqlFilter.addEQFilter("userId", userId);

		List<Trade> tradeList = findByFilter(hqlFilter);

		return tradeList.size();

	}

	@Override
	public Trade getFromRedis(String mmchnt_txn_ssn) {
		Trade trade = null;
		if (RedisCilent.existsKey(CacheConstants.TRADE + mmchnt_txn_ssn)) {
			String tradeStr = RedisCilent.getString(CacheConstants.TRADE
					+ mmchnt_txn_ssn);

			trade = JsonUtils.toBean(tradeStr, Trade.class);

			if (trade != null) {

				RedisCilent.delKey(CacheConstants.VALIDATE_TOKEN
						+ mmchnt_txn_ssn);
			}
		}

		return trade;
	}

	@Override
	public Boolean save(Trade trade) {
		Long id = LongId.get();
		trade.setId(id);
		
		Boolean result = false;
		
		if (isExist(trade)){
			logger.info("trade table 将不新增记录");
			result = true;
			return result;
		} else {
			logger.info("trade table 将新增记录");
			super.save(trade);
			result = true;
		}

		return true;
	}

	@Override
	public Integer getTotalDJCount(Long userId) {

		String sql = "SELECT count(*)  FROM t_trade_info where  showStatus = 1 and userId = "
				+ userId + " and type = 3 and orderId not in  "
				+ " ( select orderId from  t_trade_info where userId = "
				+ userId + " and type = 4 )";

		logger.info("sql = " + sql);
		Integer size = jdbcTemplate.queryForObject(sql, Integer.class);
		logger.info("size " + size);
		return size == null ? 0 : size;
	}

	@Override
	public void writeTradeFile(Trade trade, String logFilePath) {
		Long cts = System.currentTimeMillis();
		String pathName = "fyRechargeRecord-"
				+ DateUtil.transferLongToDate("yyyyMM", cts) + ".txt";
		Path filePath = Paths.get(logFilePath + pathName);
		StringBuilder payRecordBuild = getChongZhiRecordString(trade);
		if (!Files.exists(filePath)) {
			try {
				StringBuilder fileStr = new StringBuilder();
				fileStr.append("0 | | 1\r\n").append(
						"序号|用户id|客户手机号|充值金额 |商户代码|请求流水号|响应码|创建时间\r\n");
				fileStr.append(payRecordBuild);

				Files.write(filePath, fileStr.toString().getBytes("UTF-8"));
			} catch (IOException e) {
				logger.error("首次写充值文件失败！", e);
			}
		} else {// 存在则追加
			try {
				Files.write(filePath,
						payRecordBuild.toString().getBytes("UTF-8"),
						StandardOpenOption.APPEND);
			} catch (IOException e) {
				logger.error("追加写充值文件失败！", e);
			}

		}

	}

	@Override
	public void hiddenRecordByContractNo(String contract_no) {

		if (StringHelper.isEmpty(contract_no)  ) {
			return ;
		}

		HqlFilter hqlFilter = new HqlFilter();
		hqlFilter.addEQFilter("contract_no", contract_no);

		List<Trade> tradeList = this.findByFilter(hqlFilter);

		if (tradeList != null && tradeList.size() > 0) {
				for(Trade trade:tradeList){
					trade.setShowStatus(0);
					logger.info("will hidden the trade redoad id={}", trade.getId());
					this.update(trade);
				}

		}
	}

	/**
	 * 将富有返回的充值记录转换为String
	 * 
	 * @param cz
	 */
	public StringBuilder getChongZhiRecordString(Trade cz) {
		StringBuilder payRecordStringBuilder = new StringBuilder();
		if (!RedisCilent.existsKey(PayConstants.PAY_RECHARGE_RECORD)) {
			RedisCilent.setString(PayConstants.PAY_RECHARGE_RECORD,
					String.valueOf(0));
		}
		int payCount = Integer.parseInt(RedisCilent
				.getString(PayConstants.PAY_RECHARGE_RECORD));
		payCount++;
		payRecordStringBuilder.append(payCount + "|" + cz.getUserId() + "|"
				+ cz.getLogin_id() + "|" + cz.getAmt() + "|"
				+ cz.getMchnt_txn_ssn() + "|" + cz.getResp_code() + "|"
				+ DateUtil.longToLongDate(cz.getCts()) + "\r\n");
		RedisCilent.setString(PayConstants.PAY_RECHARGE_RECORD,
				String.valueOf(payCount));
		return payRecordStringBuilder;
	}

	@Override
	public Boolean isExist(Trade trade){
		
		int type = trade.getType();
		Long orderId = trade.getOrderId();
		String resp_code = trade.getResp_code();
		
		logger.info("errorExist type ={},orderId={}, resp_code={}",type,orderId, resp_code );
		
		Boolean result = false;
		
		
		
		if((type == ConstantFYJZH.TRADE_TY_YSQ 
				|| type == ConstantFYJZH.TRADE_TY_GM
				|| type == ConstantFYJZH.TRADE_TY_HK)
				&& orderId != null
				&& StringHelper.isNotEmpty(resp_code)){
			
			List<Trade> tradeList = null;
			
			HqlFilter hqlFilter = new HqlFilter();
			
			hqlFilter.addEQFilter("orderId", orderId);
			
			hqlFilter.addEQFilter("resp_code", resp_code);
			
			hqlFilter.addEQFilter("type", type);
			
			tradeList = findByFilter(hqlFilter);
			
			if (tradeList != null && tradeList.size() > 0) {
				result = true;
				logger.info("相关记录在trade 表中已存在，将不再添加。");
			}else{
				result = false;
				logger.info("相关记录在trade 表中不存在，将添加。");
			}
		}
		
		return result;
		
	}
	public void addRecord(Long orderId, Long userId, BigDecimal amount, String flowType, int type,
			String mchnt_txn_ssn, String tradeDesc, String resp_code, String resp_desc){
		Trade trade = new Trade();
		trade.setOrderId(orderId);
		trade.setUserId(userId);
		trade.setAmt(amount);
		trade.setCts(System.currentTimeMillis());
		trade.setMchnt_txn_ssn(mchnt_txn_ssn);
		trade.setFlowType(flowType);
		trade.setType(type);
		trade.setTradeDesc(tradeDesc);
		trade.setResp_code(resp_code);
		trade.setResp_desc(resp_desc);
		save(trade);
	}



	@Override
	public void sendErrorMsg(String msg, String emailMsgTitle, String emailMsgContent){


		//调用多线程生成合同
		try {
			ExecutorService executor = Executors.newFixedThreadPool(1);
			Runnable task = () -> {
                MsgUtils.sendMsg(template, msg, errorMsgPhoneListStr);
                String [] errorMsgMailArray =  errorMsgMailListStr.split(",");
                MsgUtils.sendEmailList(template,  emailMsgContent, emailMsgTitle, errorMsgMailArray);
            };
			executor.execute(task);
			executor.shutdown();

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	@Override
	public String getProductNameByTrade(Trade trade) {
		Long orderId = trade.getOrderId();

		OrderInfo orderInfo = orderJpa.findById(orderId);

		Long productId = orderInfo.getProductId();

		ProductInfo productInfo = productJpa.findById(productId);

		if(productInfo == null ){
			return "";
		}
		return  productInfo.getName();
	}
}
